package eval.engine.cplex.InitialCplexCode;

import java.io.File;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Yosef Moatti
 * 
 * moatti@il.ibm.com
 *         
 */
public class CplexAdapter  {

	final static Class<CplexAdapter> sCLASS = CplexAdapter.class;
	final static String CLASSNAME = sCLASS.getName(); 
	final static Logger sLOGGER = Logger.getLogger("vsilogger.debug");
	final static Logger essentialLogger = Logger.getLogger("vsilogger.debug");

	private final static String CPLEX_PROPERTY_PREFIX  = "vsi.config.cplex.";
	private final static String WRITE_TO_FILE   = "writeCplexInputToFile";
	private final static String CPLEX_FILE_PATH = "vsi.cplex.input.development.file.path";

	static String DIRECTORY_PATH = null;  // retrieved anew at each computePlacement invocation
	public static boolean COLLECT_CPLEX_FILES_TO_FILE = false; // retrieved anew at each computePlacement invocation
	final static Level CPLEX_INPUT_JOURNAL_LEVEL_DEFAULT_VALUE = Level.FINE;  
	static Level cplexInputJournalLevel = CPLEX_INPUT_JOURNAL_LEVEL_DEFAULT_VALUE;
	static final String separator = System.getProperty("file.separator");
	static String FILE_BASE_NAME  = "CplexInputData";
  
	//empty constructor
	public CplexAdapter() {
	}

	private boolean writeInputToFile(Properties props) {
		boolean collectInputAsFile = false;
		try { 
			collectInputAsFile = new Boolean(props.getProperty((CPLEX_PROPERTY_PREFIX + WRITE_TO_FILE)).trim());
		} catch (Exception e) {
			collectInputAsFile = false;
		}
		return collectInputAsFile;
	}

	public CplexDataHolder computePlacement(String cplexInputString,int nbVms,int nbHosts) {
		@SuppressWarnings("unused")
		String METHOD = "computePlacement";

		// Need to get the property always because the user may turn on or off debugging dynamically.
//		Properties props = Configuration.getInstance().getServiceConfigProperties();
//		COLLECT_CPLEX_FILES_TO_FILE = writeInputToFile(props);
		DIRECTORY_PATH = getDirectoryPath();
		if (COLLECT_CPLEX_FILES_TO_FILE)
			possiblyCreateDirectory();
		
		essentialLogger.finer("Building model");
		CplexPlacementModel model = new CplexPlacementModel(cplexInputString,nbVms,nbHosts);//////
		essentialLogger.finer("Model built");

//		CplexPlacement placement ;//= new CplexPlacement();
		CplexDataHolder dataHolder;
		if (nbVms > 0) {
			try {
				essentialLogger.finer("Solving model");
				dataHolder = model.getPlacement();
				essentialLogger.finer("Model solved");
			} catch (CplexDataSourceException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
		else{
			dataHolder = new CplexDataHolder(nbVms);

		}
		
		
//		
//		sLOGGER.info("Computed placement: " + placement);
///**
// * Amit: getPlacedVEIDs() was added in Iplacement
// */
//		essentialLogger.finest("Placed VS " + placement.getPlacedVEIDs().size()
//				+ "/" + env.getVirtualConfiguration().getAllVEs().size());
//		
///**
//* Amit: getPlacedPEIDs() was added in Iplacement
//*/
//		essentialLogger.finest("Placed PE: " + placement.getPlacedPEIDs().size()
//				+ "/" + env.getPhysicalConfiguration().getAllPEs().size());
//
//		essentialLogger.finer("Computed CPLEX placement");
		return dataHolder;
	}

  	/**
	 * @param dIRECTORY_PATH2
	 */
	private void possiblyCreateDirectory() {
		File directory = new File(DIRECTORY_PATH);
		if (!directory.isDirectory())
			directory.mkdirs();	
	}

	/**
	 * @return the directory path where the CPLEX input data files will be written.  
	 * If the path exists it is returned with an appended separator
	 * It it does not exist, an empty String is returned
	 */
	private String getDirectoryPath() {
//		String directoryPath = CplexAdapter.DIRECTORY_PATH;
		return "logs\\cplexInput\\";
//		Properties props = Configuration.getInstance().getServiceConfigProperties();
//		String path = props.getProperty(CPLEX_FILE_PATH);
//		if (path == null) {
//			path = "";
//		} else {
//			path = path.trim();
//			if (!path.endsWith(separator)) {
//				path = path + separator;
//			}
//		}
//		directoryPath = path;
//
//		return directoryPath;
	}

	@Override
	public String toString() {
		return CLASSNAME;
	}
	
	
}
